package com.jdd.modules.system.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jdd.common.api.vo.Result;
import com.jdd.common.exception.JddBootException;
import com.jdd.common.util.CacheUtil;
import com.jdd.common.util.RestTemplateUtils;
import com.jdd.common.util.SnowFlakeUtil;
import com.jdd.modules.area.entity.ChargeRules;
import com.jdd.modules.area.entity.ChargeRulesModule;
import com.jdd.modules.area.entity.ChargeRulesModuleStep;
import com.jdd.modules.area.entity.ParkAreaInfo;
import com.jdd.modules.area.service.IChargeRulesModuleService;
import com.jdd.modules.area.service.IChargeRulesModuleStepService;
import com.jdd.modules.area.service.IChargeRulesService;
import com.jdd.modules.area.service.IParkAreaInfoService;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.configcartype.service.IConfigCarTypeService;
import com.jdd.modules.parkcar.entity.*;
import com.jdd.modules.parkcar.service.IParkCarMonthlyService;
import com.jdd.modules.parkcar.service.IParkCarStoredService;
import com.jdd.modules.parkcar.service.IParkSpaceService;
import com.jdd.modules.parkcar.service.IParkWhiteListService;
import com.jdd.modules.parking.entity.*;
import com.jdd.modules.parking.service.*;
import com.jdd.modules.parkmonthly.entity.*;
import com.jdd.modules.parkmonthly.service.*;
import com.jdd.modules.system.entity.SysDataSyncRecord;
import com.jdd.modules.system.entity.SysUser;
import com.jdd.modules.system.mapper.BackupDataMapper;
import com.jdd.modules.system.service.ISysDataSyncRecordService;
import com.jdd.modules.system.service.ISysUserService;
import com.jdd.modules.system.vo.ParkWhiteListVO;
import com.jdd.modules.system.vo.SynchronousParkWhiteListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 同步工具类
 * TODO:
 * 1. 备份表名要存储到record中
 * 2. 等云端monthlyPeromissionGroupService 添加完后，打开相应注释即可
 */
@Component
@Slf4j
public class SyncUtil {

    //车场基本信息
    public static final String PARK_BASE_INFO="park_base_info";
    //月租车（旧）通行权限配置信息
    public static final String PARK_THROUGH="park_through";
    //计费规则配置信息
    public static final String PARK_CHARGE_RULES="park_charge_rules";
    //月租车（新）相关业务数据
    public static final String PARK_MONTHLY="park_monthly";
    //储值车相关业务数据
    public static final String PARK_STORED="park_stored";
    //黑白名单车辆
    public static final String BLACK_WHITE_LIST="black_white_list";
    //操作员信息
    public static final String PARK_OPERATOR="park_operator";
    //更新成功标志 : 1
    public static final Byte  SYNC_SUCCESS = Byte.valueOf("1");
    //更新失败标志 : 2
    public static final Byte  SYNC_FAILED = Byte.valueOf("2");

    private String cloudDataURL="";

    @PostConstruct
    void init(){
        cloudDataURL="";
    }

    @Value("${parkInfo.parkCode}")
    public String parkCode;


    private String springCloudUri;
    @Resource
    private IParkSpaceService spaceService;
    @Autowired
    private ISysDataSyncRecordService syncRecordService;
    @Autowired
    private BackupDataMapper backupDataMapper;
    @Resource
    private RestTemplateUtils restTemplateUtils;
    @Autowired
    private IParkInfoService parkInfoService;
    @Autowired
    private IConfigParkInfoService configParkInfoService;
    @Autowired
    private IParkAreaInfoService parkAreaInfoService;
    @Autowired
    private IParkArmInfoService parkArmInfoService;
    @Autowired
    private IConfigParkThroughService configParkThroughService;
    @Autowired
    private IParkCarMonthlyService parkCarMonthlyService;
    @Autowired
    private IChargeRulesService chargeRulesService;
    @Autowired
    private IChargeRulesModuleService chargeRulesModuleService;
    @Autowired
    private IMonthlyCarConfigService monthlyCarConfigService;
    @Autowired
    private IMonthlyCarOwnerService monthlyCarOwnerService;
    @Autowired
    private IMonthlyCarTypeConvertService monthlyCarTypeConvertService;
    @Autowired
    private IMonthlyCardEditInfoService monthlyCardEditInfoService;
    @Autowired
    private IMonthlyCardInfoService monthlyCardInfoService;
    @Autowired
    private IMonthlyDepartmentService monthlyDepartmentService;
    @Autowired
    private IMonthlyPackageInfoService monthlyPackageInfoService;
    @Autowired
    private IMonthlyPeromissionGroupService monthlyPeromissionGroupService;
    @Autowired
    private IParkCarStoredService parkCarStoredService;
    @Autowired
    private IConfigCarTypeService configCarTypeService;
    @Autowired
    private IConfigParkChargeService configParkChargeService;
    @Autowired
    private IParkWhiteListService parkWhiteListService;
    @Autowired
    private ISysUserService sysUserService;
    @Resource
    private IPermissionGroupService permissionGroupService;
    @Resource
    private IPermissionAreaService  permissionAreaService;
    @Resource
    private CacheUtil cacheUtil;
    @Resource
    private IChargeRulesModuleStepService chargeRulesModuleStepService;
    /**
     * 同步所有数据
     */
    public void syncAllConfig(){
        log.info("开始同步所有数据");
        syncBaseInfo();
        //syncParkthrough();
        syncCharge();
        syncNewMonthlyInfo();
        syncStoreInfo();
        //下个版本再更新
         syncBlackWhiteData();
//        syncSysUser();
        log.info("同步所有数据完成");
    }

    /**
     * 同步单条数据
     * @param configName
     */
    public void syncByConfigName(String configName){
        switch (configName){
            case PARK_BASE_INFO:
                syncBaseInfo();
                break;
//            case PARK_THROUGH:
//                syncParkthrough();
//                break;
            case PARK_CHARGE_RULES:
                syncCharge();
                break;
            case PARK_MONTHLY:
                syncNewMonthlyInfo();
                break;
            case PARK_STORED:
                syncStoreInfo();
                break;
            case BLACK_WHITE_LIST:

                syncBlackWhiteData();
                break;
            case PARK_OPERATOR:
                log.warn("测试期间暂不支持，会影响所有的测试用户");
                throw new JddBootException("暂不支持,"+configName);
            default:
                log.error("不支持的类型"+configName);
                throw new JddBootException("不支持的类型"+configName);
        }

    }


    /**
     * 备份并清空原有表
     * @param syncInfo
     * @return
     */
    private void backupAndCleanTables(Map<IService,Class> syncInfo,Map<String,String> backupMap){
        syncInfo.entrySet().stream()
                .filter(entry->entry.getKey().count()>0)
                .forEach(entry->{
                    Class value = entry.getValue();
                    String tableName = TableInfoHelper.getTableInfo(value).getTableName();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
                    String date = simpleDateFormat.format(new Date());
                    String newTableName=tableName+date;
                    backupDataMapper.createNewTableAndInsertData(newTableName, tableName);
                    log.info(tableName+"备份成功,备份表名为:"+newTableName);
                    backupMap.put(tableName,newTableName);
                    backupDataMapper.truncateTable(tableName);
                    log.info(tableName+"清空成功");
                });
    }

    /**
     * 从云端获取数据
     * @return
     */
    private Result getInfoFromCloud(Map paramMap, String url) {
        log.info("云端获取数据"+url+",参数"+ JSON.toJSONString(paramMap));
        String s = JSON.toJSONString(paramMap);
        ResponseEntity<Result> post = restTemplateUtils.post(url, s, Result.class);
        return post.getBody();

    }

    /**
     * 解析并批量插入数据
     * @param jsonObject  ： 云端解析数据
     * @param service     :  service
     * @param clazz       ： 目标类
     * @param <T>
     */
    private <T> void insertData(JSONObject jsonObject,IService<T> service,Class<T> clazz){
        String tableName = TableInfoHelper.getTableInfo(clazz).getTableName();
        JSONArray jsonArray = jsonObject.getJSONArray(tableName);
        if (null==jsonArray) {
            return;
        }
        List<T> list = jsonArray.toJavaList(clazz);
        log.info(tableName+"对应的数据个数为:"+list.size());
        if(!list.isEmpty()){
            service.saveBatch(list);
            log.info(tableName+"插入数据成功");
        }
    }

    /**
     * 同步停车场基本信息
     */
    private void syncBaseInfo(){
            log.info("开始同步停车场信息");
            Result infoFromCloud;
            Map<String,String> backupMap=new HashMap<>();
            try {
                //1. 获取云端数据
                HashMap<String,String> map=new HashMap<String, String>();
                map.put("parkCode",parkCode);
                map.put("logo",PARK_BASE_INFO);
                log.info("停车场发送信息:"+cloudDataURL+":"+parkCode);
                infoFromCloud = getInfoFromCloud(map, cloudDataURL);
                if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                    throw new RuntimeException("停车场获取云端数据失败");
                }
                log.info("停车场信息云端数据获取成功");
                String str = cacheUtil.get("ConfigParkInfo", "getConfigParkInfo");
                if (null!=str){
                    cacheUtil.delete("ConfigParkInfo", "getConfigParkInfo");
                }
                //2. 获取成功后 ，备份数据表， 并清空原有表
                HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
                serviceClassHashMap.put(parkInfoService, ParkInfo.class);
                serviceClassHashMap.put(configParkInfoService, ConfigParkInfo.class);
                serviceClassHashMap.put(parkAreaInfoService, ParkAreaInfo.class);
                serviceClassHashMap.put(parkArmInfoService, ParkArmInfo.class);
                serviceClassHashMap.put(configCarTypeService, ConfigCarType.class);
                serviceClassHashMap.put(configParkThroughService,ConfigParkThrough.class);
                backupAndCleanTables(serviceClassHashMap,backupMap);
                log.info("停车场场端数据备份并清空");

                //3. 更新表
                JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
                JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_BASE_INFO);
                //插入表数据
                insertData(baseInfoObject,parkInfoService,ParkInfo.class);
                insertData(baseInfoObject,configParkInfoService,ConfigParkInfo.class);
                insertData(baseInfoObject,parkAreaInfoService,ParkAreaInfo.class);
                insertData(baseInfoObject,parkArmInfoService,ParkArmInfo.class);
                insertData(baseInfoObject,configCarTypeService, ConfigCarType.class);
                insertData(baseInfoObject,configParkThroughService,ConfigParkThrough.class);
                log.info("停车场基本数据插入完成");

                //4. 添加状态
                addStatus(PARK_BASE_INFO,SYNC_SUCCESS,backupMap);
                log.info("停车场数据同步完成");

            }catch (Exception e){
                log.error("同步停车场信息云端数据失败",e);
                addStatus(PARK_BASE_INFO,SYNC_FAILED,backupMap);
                throw new JddBootException("同步停车场云端数据失败",e);
            }

    }

    /**
     * 月租车(旧)配置信息
     */
//    private void syncParkthrough(){
//        log.info("开始同步月租车(旧)配置信息");
//        Result infoFromCloud;
//        Map<String,String> backupMap=new HashMap<>();
//        try {
//            //1. 获取云端数据
//            HashMap<String,String> map=new HashMap<String, String>();
//            map.put("parkCode",parkCode);
//            map.put("logo",PARK_THROUGH);
//            log.info("月租车(旧)信息:"+cloudDataURL+":"+parkCode);
//            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
//
//            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
//                throw new RuntimeException("月租车(旧)获取云端数据失败");
//            }
//            log.info("月租车(旧)信息云端数据获取成功");
//
//            //2. 获取成功后 ，备份数据表， 并清空原有表
//            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
//            serviceClassHashMap.put(parkCarMonthlyService, ParkCarMonthly.class);
//            backupAndCleanTables(serviceClassHashMap,backupMap);
//            log.info("月租车(旧)配置数据备份并清空");
//
//            //3. 更新表
//            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
//            JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_THROUGH);
//            //插入表数据
//            insertData(baseInfoObject,parkCarMonthlyService,ParkCarMonthly.class);
//            log.info("月租车(旧)插入完成");
//
//            //4. 添加状态
//            addStatus(PARK_THROUGH,SYNC_SUCCESS,backupMap);
//            log.info("月租车(旧)同步完成");
//
//        }catch (Exception e){
//            log.error("月租车(旧)配置更新失败",e);
//            addStatus(PARK_THROUGH,SYNC_FAILED,backupMap);
//            throw new JddBootException("月租车(旧)配置更新失败",e);
//        }
//    }


    /**
     * 计费规则配置信息
     */
    private void syncCharge(){
        log.info("开始同步月租车通行权限配置信息");
        Result infoFromCloud;
        Map<String,String> backupMap=new HashMap<>();
        try {
            //1. 获取云端数据
            HashMap<String,String> map=new HashMap<String, String>();
            map.put("parkCode",parkCode);
            map.put("logo",PARK_CHARGE_RULES);
            log.info("计费规则配置信息:"+cloudDataURL+":"+parkCode);
            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                throw new RuntimeException("计费规则配置信息获取云端数据失败");
            }
            log.info("计费规则配置信息云端数据获取成功");

            //2. 获取成功后 ，备份数据表， 并清空原有表
            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
            serviceClassHashMap.put(chargeRulesService, ChargeRules.class);
            serviceClassHashMap.put(chargeRulesModuleService,ChargeRulesModule.class);
            serviceClassHashMap.put(configParkChargeService, ConfigParkCharge.class);
            serviceClassHashMap.put(chargeRulesModuleStepService, ChargeRulesModuleStep.class);
            backupAndCleanTables(serviceClassHashMap,backupMap);
            log.info("计费规则配置信息备份并清空");

            //3. 更新表
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
            JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_CHARGE_RULES);
            //插入表数据
            insertData(baseInfoObject,chargeRulesService,ChargeRules.class);
            insertData(baseInfoObject,chargeRulesModuleService, ChargeRulesModule.class);
            insertData(baseInfoObject,configParkChargeService, ConfigParkCharge.class);
            insertData(baseInfoObject,chargeRulesModuleStepService,ChargeRulesModuleStep.class);
            log.info("计费规则配置信息插入完成");

            //4. 添加状态
            addStatus(PARK_CHARGE_RULES,SYNC_SUCCESS,backupMap);
            log.info("计费规则配置信息同步完成");

        }catch (Exception e){
            log.error("计费规则配置信息同步数据失败",e);
            addStatus(PARK_CHARGE_RULES,SYNC_FAILED,backupMap);
            throw new JddBootException("计费规则配置信息同步数据失败",e);
        }

    }


    /**
     * 月租车（新）相关业务数据
     */
    private void syncNewMonthlyInfo(){
        log.info("开始同步新版月租车配置信息");
        Result infoFromCloud;
        Map<String,String> backupMap=new HashMap<>();
        try {
            //1. 获取云端数据
            HashMap<String,String> map=new HashMap<String, String>();
            map.put("parkCode",parkCode);
            map.put("logo",PARK_MONTHLY);
            log.info("新月租车配置信息:"+cloudDataURL+":"+parkCode);
            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                throw new RuntimeException("新月租车获取云端数据失败");
            }
            log.info("新月租车配置信息云端数据获取成功");

            //2. 获取成功后 ，备份数据表， 并清空原有表
            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
            serviceClassHashMap.put(spaceService, ParkSpace.class);
            serviceClassHashMap.put(parkCarMonthlyService, ParkCarMonthly.class);
            serviceClassHashMap.put(permissionGroupService, PermissionGroup.class);
            serviceClassHashMap.put(permissionAreaService, PermissionArea.class);
            serviceClassHashMap.put(monthlyCarConfigService, MonthlyCarConfig.class);
            serviceClassHashMap.put(monthlyCardEditInfoService, MonthlyCardEditInfo.class);
            serviceClassHashMap.put(monthlyCardInfoService, MonthlyCardInfo.class);
            serviceClassHashMap.put(monthlyCarOwnerService, MonthlyCarOwner.class);
            serviceClassHashMap.put(monthlyCarTypeConvertService, MonthlyCarTypeConvert.class);
            serviceClassHashMap.put(monthlyDepartmentService, MonthlyDepartment.class);
            serviceClassHashMap.put(monthlyPackageInfoService, MonthlyPackageInfo.class);
//            serviceClassHashMap.put(monthlyPeromissionGroupService, MonthlyPeromissionGroup.class);
            backupAndCleanTables(serviceClassHashMap,backupMap);
            log.info("新月租车配置信息备份并清空");

            //3. 更新表
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
            JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_MONTHLY);
            //插入表数据
            insertData(baseInfoObject,parkCarMonthlyService, ParkCarMonthly.class);
            insertData(baseInfoObject,spaceService, ParkSpace.class);
            insertData(baseInfoObject,permissionGroupService, PermissionGroup.class);
            insertData(baseInfoObject,permissionAreaService, PermissionArea.class);
            insertData(baseInfoObject,monthlyCarConfigService, MonthlyCarConfig.class);
            insertData(baseInfoObject,monthlyCardEditInfoService, MonthlyCardEditInfo.class);
            insertData(baseInfoObject,monthlyCardInfoService, MonthlyCardInfo.class);
            insertData(baseInfoObject,monthlyCarOwnerService, MonthlyCarOwner.class);
            insertData(baseInfoObject,monthlyCarTypeConvertService, MonthlyCarTypeConvert.class);
            insertData(baseInfoObject,monthlyDepartmentService, MonthlyDepartment.class);
            insertData(baseInfoObject,monthlyPackageInfoService, MonthlyPackageInfo.class);
//            insertData(baseInfoObject,monthlyPeromissionGroupService, MonthlyPeromissionGroup.class);
            log.info("新月租车配置信息插入完成");

            //4. 添加状态
            addStatus(PARK_MONTHLY,SYNC_SUCCESS,backupMap);
            log.info("新月租车同步完成");

        }catch (Exception e){
            log.error("新月租车配置信息获取云端数据失败",e);
            addStatus(PARK_MONTHLY,SYNC_FAILED,backupMap);
            throw new JddBootException("新月租车配置信息获取云端数据失败",e);
        }

    }


    /**
     * 储值车相关业务
     */
    private void syncStoreInfo(){
        log.info("开始同步储值车配置信息");
        Result infoFromCloud;
        Map<String,String> backupMap=new HashMap<>();
        try {
            //1. 获取云端数据
            HashMap<String,String> map=new HashMap<String, String>();
            map.put("parkCode",parkCode);
            map.put("logo",PARK_STORED);
            log.info("储值车配置信息:"+cloudDataURL+":"+parkCode);
            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                throw new RuntimeException("储值车获取云端数据失败");
            }
            log.info("储值车配置信息云端数据获取成功");

            //2. 获取成功后 ，备份数据表， 并清空原有表
            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
            serviceClassHashMap.put(parkCarStoredService, ParkCarStored.class);
            backupAndCleanTables(serviceClassHashMap,backupMap);
            log.info("储值车配置信息备份并清空");

            //3. 更新表
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
            JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_STORED);
            //插入表数据
            insertData(baseInfoObject,parkCarStoredService, ParkCarStored.class);
            log.info("储值车配置信息插入完成");

            //4. 添加状态
            addStatus(PARK_STORED,SYNC_SUCCESS,backupMap);
            log.info("储值车同步完成");

        }catch (Exception e){
            log.error("储值车配置信息同步失败",e);
            addStatus(PARK_STORED,SYNC_FAILED,backupMap);
            throw new JddBootException("储值车配置信息同步失败",e);
        }
    }


    /**
     * 同步黑白名单
     */
    private void syncBlackWhiteData(){
        log.info("开始同步黑白名单信息");
        Result infoFromCloud;
        Map<String,String> backupMap=new HashMap<>();
        try {
            //1. 获取云端数据
            HashMap<String,String> map=new HashMap<String, String>();
            map.put("parkCode",parkCode);
            map.put("logo",BLACK_WHITE_LIST);
            log.info("黑白名单配置信息:"+cloudDataURL+":"+parkCode);
            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                throw new RuntimeException("黑白名单获取云端数据失败");
            }
            log.info("黑白名单配置信息云端数据获取成功");
            //3. 更新表
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
            if (null==jsonObject){
                return;
            }
            JSONObject jsonObj = jsonObject.getJSONObject(BLACK_WHITE_LIST);
            String str = jsonObj.getString("park_white_list");
            if (null==str){
                return;
            }

            List<SynchronousParkWhiteListVO> parkBlackLists = JSON.parseArray(str , SynchronousParkWhiteListVO.class);
            log.info(parkBlackLists+"对应的数据个数为:"+parkBlackLists.size());
            if (null==parkBlackLists||parkBlackLists.isEmpty()){
                //4. 添加状态
                addStatus(BLACK_WHITE_LIST,SYNC_SUCCESS,backupMap);
                return;
            }
            //2. 获取成功后 ，备份数据表， 并清空原有表
            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
            serviceClassHashMap.put(parkWhiteListService, ParkWhiteList.class);
            backupAndCleanTables(serviceClassHashMap,backupMap);
            log.info("黑白名单配置信息备份并清空");


            parkWhiteListService.batchAdd(parkBlackLists);
            log.info("黑白名单配置信息插入完成");

            //4. 添加状态
            addStatus(BLACK_WHITE_LIST,SYNC_SUCCESS,backupMap);
            log.info("黑白名单同步完成");

        }catch (Exception e){
            log.error("黑白名单配置信息同步失败",e);
            addStatus(BLACK_WHITE_LIST,SYNC_FAILED,backupMap);
            throw new JddBootException("黑白名单配置信息同步失败",e);
        }
    }

    /**
     * 同步用户,注意： 测试期间不要使用， 会导致所有已有的用户清空
     */
    private void syncSysUser(){
        log.info("开始同步用户信息");
        Result infoFromCloud;
        Map<String,String> backupMap=new HashMap<>();
        try {
            //1. 获取云端数据
            HashMap<String,String> map=new HashMap<String, String>();
            map.put("parkCode",parkCode);
            map.put("logo",PARK_OPERATOR);
            log.info("用户配置信息:"+cloudDataURL+":"+parkCode);
            infoFromCloud = getInfoFromCloud(map, cloudDataURL);
            if(infoFromCloud==null || !infoFromCloud.isSuccess()){
                throw new RuntimeException("用户获取云端数据失败");
            }
            log.info("用户配置信息云端数据获取成功");

            //2. 获取成功后 ，备份数据表， 并清空原有表
            HashMap<IService, Class> serviceClassHashMap = new HashMap<>();
            serviceClassHashMap.put(sysUserService, SysUser.class);
            backupAndCleanTables(serviceClassHashMap,backupMap);
            log.info("用户配置信息备份并清空");

            //3. 更新表
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(infoFromCloud.getResult()));
            JSONObject baseInfoObject = jsonObject.getJSONObject(PARK_OPERATOR);
            //插入表数据
            insertData(baseInfoObject,sysUserService, SysUser.class);
            log.info("用户配置信息插入完成");

            //4. 添加状态
            addStatus(PARK_OPERATOR,SYNC_SUCCESS,backupMap);
            log.info("用户同步完成");

        }catch (Exception e){
            log.error("用户配置信息同步失败",e);
            addStatus(PARK_OPERATOR,SYNC_FAILED,backupMap);
            throw new JddBootException("用户配置信息同步失败",e);
        }
    }


    /**
     * 插入结果
     * @param dataName
     * @param result
     * @param backTableMap
     */
    private void addStatus(String dataName, Byte result,Map<String,String> backTableMap){
        SysDataSyncRecord sysDataSyncRecord = new SysDataSyncRecord();
        String backUpTableRecord="";
        if(backTableMap!=null && !backTableMap.isEmpty()){
            backUpTableRecord = backTableMap.entrySet().stream().map(entry -> "[" + entry.getKey() + "," + entry.getValue() + "]")
                    .collect(Collectors.joining("_"));
        }
        sysDataSyncRecord.setId(SnowFlakeUtil.getId()).setDataName(dataName)
                .setResult(result).setUpdateTime(new Date());
        if(!backUpTableRecord.isEmpty()){
            sysDataSyncRecord.setBackupTables(backUpTableRecord);
        }
        syncRecordService.save(sysDataSyncRecord);
    }

}
